package com.example.tool.util;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.example.tool.bean.business.wechat.AddSheetResponse;
import com.example.tool.bean.business.wechat.CreateDocResponse;
import com.example.tool.bean.business.wechat.GetDocInfoResponse;
import com.example.tool.bean.business.wechat.SmartsheetGetSheetResponse;
import com.example.tool.bean.business.wechat.SpreadSheetGetSheetPropertiesItem;
import com.example.tool.bean.business.wechat.SpreadSheetGetSheetPropertiesResponse;
import com.example.tool.bean.business.wechat.SpreadsheetUpdateRangeRequest;
import com.example.tool.bean.wcaiexcel.AddSmartSheetFieldsRequest;
import com.example.tool.bean.wcaiexcel.AddSmartSheetFieldsResponse;
import com.example.tool.bean.wcaiexcel.AddSmartSheetRecordsRequest;
import com.example.tool.bean.wcaiexcel.AddSmartSheetRecordsResponse;
import com.example.tool.bean.wcaiexcel.AddSmartSheetRequest;
import com.example.tool.bean.wcaiexcel.AddSmartSheetResponse;
import com.example.tool.bean.wcaiexcel.DeleteSmartSheetFieldsRequest;
import com.example.tool.bean.wcaiexcel.DeleteSmartSheetFieldsResponse;
import com.example.tool.bean.wcaiexcel.DeleteSmartSheetSheetRequest;
import com.example.tool.bean.wcaiexcel.DeleteSmartSheetSheetResponse;
import com.example.tool.bean.wcaiexcel.FieldQueryRequest;
import com.example.tool.bean.wcaiexcel.FieldQueryResponse;
import com.example.tool.bean.wcaiexcel.GetSmartSheetRecordsRequest;
import com.example.tool.bean.wcaiexcel.GetSmartSheetRecordsResponse;
import com.example.tool.bean.wcaiexcel.RenameDocRequest;
import com.example.tool.bean.wcaiexcel.RenameDocResponse;
import com.example.tool.bean.wcaiexcel.RobotMessage;
import com.example.tool.bean.wcaiexcel.SmartSheetQueryRequest;
import com.example.tool.bean.wcaiexcel.SmartSheetQueryResponse;
import com.example.tool.bean.wcaiexcel.WeChatFieldType;
import com.example.tool.bean.wcaiexcel.WeComApiResponse;
import com.example.tool.bean.wcaiexcel.WechatCreateMemberRequest;
import com.example.tool.bean.wcaiexcel.WechatGetUserIdByPhoneResponse;
import com.example.tool.service.RedisService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import shade.com.alibaba.fastjson2.JSON;
import shade.com.alibaba.fastjson2.JSONObject;

import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Component
public class WeChatUtil {
    @Getter
    private static RedisService redisService;
    private static final String qwAccessTokenKey = "sys:qwAccessToken:key";
    private static final String qwMemberAccessTokenKey = "sys:qwMemberAccessToken:key";
    private static final String qwWeDocDocShareKey = "sys:qwWeDocDoc:%s";
    // 企业ID
    private static final String CORP_ID = "ww100e60ad030b933b";
    // 应用Secret
    private static final String CORP_SECRET = "cHaZ2CrwFd7TXiadi3vRe80izq46V4pNqojZj3SilQc";
    // 企业通讯录Secret
    private static final String CORP_MEMBER_SECRET = "yde5CidjqBDSCVxODkrZVC-jaWKcsMWqGdRU3vO2kW4";
    // 应用ID
    private static final int AGENT_ID = 1000003;
    //    // 获取token的URL
//    private static final String GET_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
//    // 企业微信API地址
//    private static final String SEND_GROUP_MSG_URL = "https://qyapi.weixin.qq.com/cgi-bin/appchat/send";
    // 企业微信API基础URL
    private static final String BASE_URL = "https://qyapi.weixin.qq.com/cgi-bin";
    //    //创建文档api
//    private static final String CREATE_DOCUMENT_API_URL = "https://qyapi.weixin.qq.com/cgi-bin/wedoc/create_doc";
//    //查看文档
//    private static final String GET_DOC_BASE_INFO_API_URL = "https://qyapi.weixin.qq.com/cgi-bin/wedoc/get_doc_base_info";
//    //添加子表
//    private static final String ADD_SHEET_API_URL = "https://qyapi.weixin.qq.com/cgi-bin/wedoc/smartsheet/add_sheet";
//    //添加字段/表头
//    private static final String ADD_FIELDS_API_URL = "https://qyapi.weixin.qq.com/cgi-bin/wedoc/smartsheet/add_fields";
//    //添加记录
//    private static final String ADD_RECORDS_API_URL = "https://qyapi.weixin.qq.com/cgi-bin/wedoc/smartsheet/add_records";
//    //获取群聊列表
//    private static final String GROUP_CHAT_LIST_API_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list";
//    //查询子表
//    private static final String SMARTSHEET_GET_SHEET_API_URL = "https://qyapi.weixin.qq.com/cgi-bin/wedoc/smartsheet/get_sheet";
    // 带连接池的HttpClient（推荐生产环境使用）
    private static final CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setConnectTimeout(5000)
            .setSocketTimeout(10000).build()).build();
    // 常用字段类型常量
    private static final int MAX_RANGE_COLUMNS = 200; // 列数最大长度
    private static final int MAX_RANGE_ROWS = 1000; // 行数最大长度
    private static final int MAX_TOTAL_CELLS = 10000;     // 单批最大单元格数
    //管理员id
//    private static final String[] adminUsers=new String[]{"1"};
    private static final String[] adminUsers = new String[]{"ZhangDeCheng", "XuJiaChao", "ShaoDanDan"};

    @Autowired
    public void setRedisService(RedisService redisService) {
        WeChatUtil.redisService = redisService;
    }


    /**
     * 获取AccessToken
     */
    public static String getAccessToken() {
        if (!getRedisService().hasKey(qwAccessTokenKey)) {
            String url = String.format("%s/gettoken?corpid=%s&corpsecret=%s", BASE_URL, CORP_ID, CORP_SECRET);
            String result = null;
            try {
                result = HttpUtil.doGet(url);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            JSONObject resultBody = JSON.parseObject(result);
            String accessToken = resultBody.getString("access_token");
            Integer expiresIn = resultBody.getInteger("expires_in") - 1000;
            getRedisService().setWithExpire(qwAccessTokenKey, accessToken, expiresIn, TimeUnit.SECONDS);
            return accessToken;
        } else {
            return getRedisService().getString(qwAccessTokenKey);
        }
    }

    /**
     * 获取通讯录AccessToken
     */
    public static String getMemberAccessToken() {
        if (!getRedisService().hasKey(qwMemberAccessTokenKey)) {
            String url = String.format("%s/gettoken?corpid=%s&corpsecret=%s", BASE_URL, CORP_ID, CORP_MEMBER_SECRET);
            String result;
            try {
                result = HttpUtil.doGet(url);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            JSONObject resultBody = JSON.parseObject(result);
            String accessToken = resultBody.getString("access_token");
            int expiresIn = resultBody.getInteger("expires_in") - 1000;
            getRedisService().setWithExpire(qwMemberAccessTokenKey, accessToken, expiresIn, TimeUnit.SECONDS);
            return accessToken;
        } else {
            return getRedisService().getString(qwMemberAccessTokenKey);
        }
    }


    /**
     * 发送群消息基础方法
     *
     * @param messageJson 消息JSON对象
     * @return 是否发送成功
     */
    private static boolean sendGroupMessage(JSONObject messageJson) throws IOException {
        String url = String.format("%s/appchat/send?access_token=%s", BASE_URL, getAccessToken());
        String result = HttpUtil.doPost(url, messageJson.toJSONString());
        JSONObject resultJson = JSON.parseObject(result);
        return resultJson.getInteger("errcode") == 0;
    }

    /**
     * 发送文本消息
     *
     * @param chatId  群聊ID
     * @param content 消息内容
     * @param isSafe  是否保密消息
     */
    public static void sendTextMessage(String chatId, String content, boolean isSafe) {
        JSONObject message = new JSONObject();
        message.put("chatid", chatId);
        message.put("msgtype", "text");
        JSONObject text = new JSONObject();
        text.put("content", content);
        message.put("text", text);
        message.put("safe", isSafe ? 1 : 0);
        try {
            sendGroupMessage(message);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取指定群聊的详细信息
     *
     * @param chatId 群聊ID
     * @return 群聊信息JSON对象
     */
    public static JSONObject getGroupChatInfo(String chatId) throws IOException {
        String url = String.format("%s/appchat/get?access_token=%s&chatid=%s", BASE_URL, getAccessToken(), chatId);
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                String result = EntityUtils.toString(response.getEntity());
                JSONObject resultJson = JSON.parseObject(result);
                if (resultJson.getInteger("errcode") == 0) {
                    return resultJson;
                } else {
                    throw new IOException("获取群聊信息失败: " + resultJson.getString("errmsg"));
                }
            }
        }
    }


    /**
     * 发送机器人消息
     *
     * @param webhookUrl  机器人Webhook地址
     * @param messageJson 消息JSON对象
     * @return 是否发送成功
     */
    public static boolean sendMessage(String webhookUrl, JSONObject messageJson) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(webhookUrl);
            httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
            StringEntity entity = new StringEntity(messageJson.toJSONString(), "UTF-8");
            httpPost.setEntity(entity);

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String result = EntityUtils.toString(response.getEntity());
                JSONObject resultJson = JSON.parseObject(result);
                return resultJson.getInteger("errcode") == 0;
            }
        }
    }

    /**
     * 发送机器人消息
     *
     * @param webhookUrl 机器人Webhook地址
     * @return 是否发送成功
     */
    public static boolean sendMessage(String webhookUrl, RobotMessage textMessage) {
        if (!webhookUrl.contains("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=")) {
            webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=".concat(webhookUrl);
        }
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(webhookUrl);
            httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
            String requestBody = objectMapper.writeValueAsString(textMessage);
            StringEntity entity = new StringEntity(requestBody, "UTF-8");
            httpPost.setEntity(entity);

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String result = EntityUtils.toString(response.getEntity());
                JSONObject resultJson = JSON.parseObject(result);
                return resultJson.getInteger("errcode") == 0;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 发送文本消息
     *
     * @param webhookUrl          机器人Webhook地址
     * @param content             消息内容
     * @param mentionedList       要@的成员userid列表
     * @param mentionedMobileList 要@的成员手机号列表
     * @return 是否发送成功
     */
    public static boolean sendText(String webhookUrl, String content,
                                   List<String> mentionedList,
                                   List<String> mentionedMobileList) throws IOException {
        JSONObject message = new JSONObject();
        message.put("msgtype", "text");
        JSONObject text = new JSONObject();
        text.put("content", content);
        if (mentionedList != null) text.put("mentioned_list", mentionedList);
        if (mentionedMobileList != null) text.put("mentioned_mobile_list", mentionedMobileList);
        message.put("text", text);
        return sendMessage(webhookUrl, message);
    }


    /**
     * 创建企业微信文档
     *
     * @param docType  文档类型（必须）：3-文档 4-表格 10-智能表格
     * @param docName  文档名称
     * @param spaceid  空间ID（非必须
     * @param fatherid 父目录ID（非必须）
     * @return 创建结果
     * @throws Exception API调用异常
     */
    public static CreateDocResponse createDocument(Integer docType, String docName, String spaceid, String fatherid) {
        // 参数校验
        if (docType == null) {
            throw new IllegalArgumentException("doc_type不能为空");
        }
        if (docName == null || docName.trim().isEmpty()) {
            throw new IllegalArgumentException("doc_name不能为空");
        }
        if (spaceid != null && fatherid == null) {
            throw new IllegalArgumentException("指定spaceid时必须同时指定fatherid");
        }
        String url = String.format("%s/wedoc/create_doc?access_token=%s", BASE_URL, getAccessToken());
        HttpPost httpPost = new HttpPost(url);
        try {
            JSONObject param = new JSONObject();
            param.put("doc_type", docType);
            param.put("spaceid", spaceid);
            param.put("fatherid", fatherid);
            param.put("doc_name", docName);
            param.put("admin_users", adminUsers);
            // 设置JSON请求体
            String jsonBody = param.toJSONString();
            StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());

                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }

                // 解析响应
                CreateDocResponse result = JSONObject.parseObject(responseBody, CreateDocResponse.class);
                if (!result.isSuccess()) {
                    throw new RuntimeException(String.format("API调用失败[%d]: %s", result.getErrCode(), result.getErrMsg()));
                }
                return result;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 获取表格行列信息
     *
     * @param docid
     * @return
     */
    public static SpreadSheetGetSheetPropertiesResponse spreadSheetGetSheetProperties(String docid) {
        // 参数校验
        if (docid == null || docid.trim().isEmpty()) {
            throw new IllegalArgumentException("doc_type不能为空");
        }
        String url = String.format("%s/wedoc/spreadsheet/get_sheet_properties?access_token=%s", BASE_URL, getAccessToken());
        HttpPost httpPost = new HttpPost(url);
        try {
            JSONObject param = new JSONObject();
            param.put("docid", docid);
            // 设置JSON请求体
            String jsonBody = param.toJSONString();
            StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());

                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }

                // 解析响应
                SpreadSheetGetSheetPropertiesResponse result = JSONObject.parseObject(responseBody, SpreadSheetGetSheetPropertiesResponse.class);
                if (!result.isSuccess()) {
                    throw new RuntimeException(String.format("API调用失败[%d]: %s",
                            result.getErrCode(), result.getErrMsg()));
                }
                return result;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 获取表格数据
     *
     * @param docid
     * @param sheetId
     * @param range
     * @return
     */
    public static CreateDocResponse spreadSheetGetSheetRangeData(String docid, String sheetId, String range) {
        // 参数校验
        if (docid == null || docid.trim().isEmpty()) {
            throw new IllegalArgumentException("doc_type不能为空");
        }
        if (sheetId == null || sheetId.trim().isEmpty()) {
            throw new IllegalArgumentException("doc_name不能为空");
        }
        if (range != null || range.trim().isEmpty()) {
            throw new IllegalArgumentException("指定spaceid时必须同时指定fatherid");
        }
        String url = String.format("%s/wedoc/spreadsheet/get_sheet_range_data?access_token=%s", BASE_URL, getAccessToken());
        HttpPost httpPost = new HttpPost(url);
        try {
            JSONObject param = new JSONObject();
            param.put("docid", docid);
            param.put("sheetId", sheetId);
            param.put("range", range);
            // 设置JSON请求体
            String jsonBody = param.toJSONString();
            StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());

                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }

                // 解析响应
                CreateDocResponse result = JSONObject.parseObject(responseBody, CreateDocResponse.class);
                if (!result.isSuccess()) {
                    throw new RuntimeException(String.format("API调用失败[%d]: %s",
                            result.getErrCode(), result.getErrMsg()));
                }
                return result;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 获取文档基础信息
     *
     * @param docid 文档id
     * @return 创建结果
     * @throws Exception API调用异常
     */
    public static GetDocInfoResponse getDocBaseInfo(String docid) {
        if (docid == null || docid.trim().isEmpty()) {
            throw new IllegalArgumentException("docid不能为空");
        }
        // 构建请求URL
        String url = String.format("%s/wedoc/get_doc_base_info?access_token=%s", BASE_URL, getAccessToken());
        HttpPost httpPost = new HttpPost(url);
        try {
            JSONObject param = new JSONObject();
            param.put("docid", docid);
            // 设置JSON请求体
            String jsonBody = param.toJSONString();
            StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());
                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }
                // 解析响应
                GetDocInfoResponse result = JSONObject.parseObject(responseBody, GetDocInfoResponse.class);
                if (!result.isSuccess()) {
                    throw new RuntimeException(String.format("API调用失败[%d]: %s", result.getErrCode(), result.getErrMsg()));
                }
                return result;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 获取文档数据
     *
     * @param docid 文档id
     * @return 创建结果
     * @throws Exception API调用异常
     */
    public static JSONObject documentInfoGet(String docid) {
        // 参数校验
        if (docid == null || docid.trim().isEmpty()) {
            throw new IllegalArgumentException("docid不能为空");
        }
        String url = String.format("%s/wedoc/document/get?access_token=%s", BASE_URL, getAccessToken());
        // 构建请求URL
        HttpPost httpPost = new HttpPost(url);

        try {
            JSONObject param = new JSONObject();
            param.put("docid", docid);
            // 设置JSON请求体
            String jsonBody = param.toJSONString();
            StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());

                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }

                // 解析响应
                JSONObject result = JSONObject.parseObject(responseBody);

                return result;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 批量更新表格内容
     *
     * @param docId    文档ID
     * @param requests 批量操作请求列表
     * @return 返回结果
     */
    public static JSONObject batchUpdateSpreadsheet(String docId, JSONObject... requests) {
        String url = String.format("%s/wedoc/spreadsheet/batch_update?access_token=%s", BASE_URL, getAccessToken());
        // 构建请求体
        JSONObject requestBody = new JSONObject();
        requestBody.put("docid", docId);
        requestBody.put("requests", Arrays.stream(requests).toArray(JSONObject[]::new));

        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/json");

        try {
            httpPost.setEntity(new StringEntity(requestBody.toJSONString(), "UTF-8"));
            CloseableHttpResponse response = httpClient.execute(httpPost);
            String responseStr = EntityUtils.toString(response.getEntity(), "UTF-8");
            return JSON.parseObject(responseStr);
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject errorResult = new JSONObject();
            errorResult.put("errcode", -1);
            errorResult.put("errmsg", "请求异常: " + e.getMessage());
            return errorResult;
        }
    }

    /**
     * 创建群
     *
     * @param name
     * @param owner      管理员
     * @param chatId
     * @param adminUsers
     */
    private static void appChatCreate(String name, String owner, String chatId, String[] adminUsers) {
        String url = String.format("%s/appchat/create?access_token=%s", BASE_URL, getAccessToken());

        try {
            // 创建请求体JSON
            JSONObject requestBody = new JSONObject();
            requestBody.put("name", name);
            requestBody.put("owner", owner);
            requestBody.put("chatid", chatId); // 可选参数使用putOpt
            requestBody.put("userlist", adminUsers);

            // 创建HTTP POST请求
            HttpPost httpPost = new HttpPost(new URI(url));
            httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
            httpPost.setEntity(new StringEntity(requestBody.toString(), "UTF-8"));

            // 执行请求
            try (CloseableHttpClient httpClient = HttpClients.createDefault();
                 CloseableHttpResponse response = httpClient.execute(httpPost)) {

                // 处理响应
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    String responseString = EntityUtils.toString(responseEntity, "UTF-8");
                    JSONObject jsonResponse = JSONObject.parseObject(responseString);


                    if (jsonResponse.getInteger("errcode") == 0) {
                        System.out.println("群聊创建成功，chatid: " + jsonResponse.getString("chatid"));
                    } else {
                        System.out.println("群聊创建失败: " + jsonResponse.getString("errmsg"));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取智能文档
     *
     * @param docid 文档id
     * @return 创建结果
     * @throws Exception API调用异常
     */
    public static SmartsheetGetSheetResponse smartSheetGetSheet(String docid, String sheetId) {
        // 参数校验
        if (docid == null || docid.trim().isEmpty()) {
            throw new IllegalArgumentException("docid不能为空");
        }
        // 构建请求URL
        String url = String.format("%s/wedoc/smartsheet/get_sheet?access_token=%s", BASE_URL, getAccessToken());
        HttpPost httpPost = new HttpPost(url);
        try {
            JSONObject param = new JSONObject();
            param.put("docid", docid);
            param.put("sheet_id", sheetId);
            // 设置JSON请求体
            String jsonBody = param.toJSONString();
            StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());

                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }

                // 解析响应
                SmartsheetGetSheetResponse result = JSONObject.parseObject(responseBody, SmartsheetGetSheetResponse.class);
                if (!result.isSuccess()) {
                    throw new RuntimeException(String.format("API调用失败[%d]: %s",
                            result.getErrCode(), result.getErrMsg()));
                }
                return result;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            httpPost.releaseConnection();
        }
    }


    /**
     * 1
     * 在文档中添加智能子表
     *
     * @param docid
     * @param title
     * @param index
     * @return 添加结果
     * @return
     */
    public static AddSheetResponse addSmartSheetSheet(String docid, String title, Integer index) {
        if (docid == null || docid.trim().isEmpty()) {
            throw new IllegalArgumentException("docid不能为空");
        }

        // 构建请求URL
        String url = String.format("%s/wedoc/smartsheet/add_sheet?access_token=%s", BASE_URL, getAccessToken());
        HttpPost httpPost = new HttpPost(url);

        try {
            // 设置JSON请求体
            JSONObject param = new JSONObject();
            param.put("docid", docid);
            JSONObject properties = new JSONObject();
            properties.put("title", title);
            properties.put("index", index);
            param.put("properties", properties);
            String jsonBody = param.toJSONString();
            StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());

                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }
                // 解析响应
                AddSheetResponse result = JSONObject.parseObject(responseBody, AddSheetResponse.class);
                if (!result.isSuccess()) {
                    throw new RuntimeException(String.format("API调用失败[%d]: %s",
                            result.getErrCode(), result.getErrMsg()));
                }
                return result;
            } catch (ClientProtocolException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            httpPost.releaseConnection();
        }
    }

    /*  *//**
     * 在智能表格中添加字段
     *
     * @param docid   文档id
     * @param sheetid 表格id
     * @param fields  字段详情
     * @return 添加结果
     * @throws Exception API调用异常
     *//*
    public static AddFieldsResponse addSmartSheetFields(String docid, String sheetid, List<AddFieldsRequest> fields) throws Exception {
        if (docid == null || docid.trim().isEmpty()) {
            throw new IllegalArgumentException("docid不能为空");
        }
        if (sheetid == null || sheetid.trim().isEmpty()) {
            throw new IllegalArgumentException("sheet_id不能为空");
        }
        if (fields == null || fields.isEmpty()) {
            throw new IllegalArgumentException("fields不能为空");
        }
        for (AddFieldsRequest field : fields) {
            if (field.getField_title() == null || field.getField_title().trim().isEmpty()) {
                throw new IllegalArgumentException("field_title不能为空");
            }
            if (field.getField_type() == null || field.getField_type().trim().isEmpty()) {
                throw new IllegalArgumentException("field_type不能为空");
            }
        }

        // 构建请求URL
        String url = String.format("%s/wedoc/smartsheet/add_fields?access_token=%s", BASE_URL, getAccessToken());
        HttpPost httpPost = new HttpPost(url);
        JSONObject param = new JSONObject();
        try {
            param.put("docid", docid);
            param.put("sheet_id", sheetid);
            param.put("fields", fields);
            // 设置JSON请求体
            String jsonBody = param.toJSONString();
            StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());

                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }

                // 解析响应
                AddFieldsResponse result = JSONObject.parseObject(responseBody, AddFieldsResponse.class);
                if (!result.isSuccess()) {
                    throw new RuntimeException(String.format("API调用失败[%d]: %s",
                            result.getErrcode(), result.getErrmsg()));
                }
                return result;
            }
        } finally {
            httpPost.releaseConnection();
        }
    }*/

    /**
     * 批量在智能表格中添加字段
     *
     * @param docid     文档id
     * @param sheetid   表格id
     * @param allFields 数据
     * @param batchSize 分批次数
     * @return 添加结果
     * @throws Exception API调用异常
     */
    public static List<AddSmartSheetFieldsResponse> addSmartSheetFieldsBatch(String docid, String sheetid, List<AddSmartSheetFieldsRequest.AddField> allFields, int batchSize) throws Exception {
        List<AddSmartSheetFieldsResponse> responses = new ArrayList<>();
        for (int i = 0; i < allFields.size(); i += batchSize) {
            int end = Math.min(i + batchSize, allFields.size());
            List<AddSmartSheetFieldsRequest.AddField> batchFields = allFields.subList(i, end);
            responses.add(addSmartSheetFields(docid, sheetid, batchFields));
        }
        return responses;
    }

    /**
     * 在智能表格中添加记录
     *
     * @return 添加结果
     * @throws Exception API调用异常
     */
    public static AddSmartSheetRecordsResponse addSmartSheetRecords(String docid, String sheetId, String keyType, List<AddSmartSheetRecordsRequest.Record> records) {
        // 参数校验
        if (docid == null || docid.trim().isEmpty()) {
            throw new IllegalArgumentException("docid不能为空");
        }
        if (sheetId == null || sheetId.trim().isEmpty()) {
            throw new IllegalArgumentException("sheet_id不能为空");
        }
        if (records == null || records.isEmpty()) {
            throw new IllegalArgumentException("records不能为空");
        }
        for (AddSmartSheetRecordsRequest.Record record : records) {
            if (record.getValues() == null || record.getValues().isEmpty()) {
                throw new IllegalArgumentException("record.values不能为空");
            }
        }
        String url = String.format("%s/wedoc/smartsheet/add_records?access_token=%s", BASE_URL, getAccessToken());
//        // 构建请求URL
//        String urlWithToken = ADD_RECORDS_API_URL + "?access_token=" + getAccessToken();
        HttpPost httpPost = new HttpPost(url);
        if (StringUtils.isBlank(keyType)) {
            keyType = "CELL_VALUE_KEY_TYPE_FIELD_TITLE";
        }

        AddSmartSheetRecordsRequest request = new AddSmartSheetRecordsRequest();


        try {
            request.setKey_type(keyType);
            request.setSheet_id(sheetId);
            request.setDocid(docid);
            request.setRecords(records);
//            JSONObject param = new JSONObject();
//            param.put("keyType", keyType);
//            param.put("docid", docid);
//            param.put("sheetId", sheetId);
//            param.put("records", records);
            // 设置JSON请求体
//            String jsonBody = param.toJSONString();
//            System.out.println(jsonBody);
            String requestBody = objectMapper.writeValueAsString(request);
            System.out.println(requestBody);
            StringEntity entity = new StringEntity(requestBody, StandardCharsets.UTF_8);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity());
                if (statusCode != HttpStatus.SC_OK) {
                    throw new RuntimeException("HTTP请求失败，状态码: " + statusCode);
                }
                AddSmartSheetRecordsResponse apiResponse = objectMapper.readValue(responseBody, AddSmartSheetRecordsResponse.class);
                if (!apiResponse.isSuccess()) {
                    throw new RuntimeException(String.format("API调用失败[%d]: %s", apiResponse.getErrCode(), apiResponse.getErrMsg()));
                }
                return apiResponse;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 批量新增
     *
     * @param docid
     * @param sheetId
     * @param keyType
     * @param allRecords
     * @param batchSize
     * @return
     * @throws Exception
     */
    public static List<AddSmartSheetRecordsResponse> addSmartSheetRecordsBatch(String docid, String sheetId, String keyType, List<AddSmartSheetRecordsRequest.Record> allRecords, int batchSize) {
        List<AddSmartSheetRecordsResponse> responses = new ArrayList<>();

        for (int i = 0; i < allRecords.size(); i += batchSize) {
            int end = Math.min(i + batchSize, allRecords.size());
            List<AddSmartSheetRecordsRequest.Record> batchRecords = allRecords.subList(i, end);

            AddSmartSheetRecordsRequest batchRequest = new AddSmartSheetRecordsRequest();
            batchRequest.setDocid(docid);
            batchRequest.setSheet_id(sheetId);
            batchRequest.setKey_type(keyType);
            batchRequest.setRecords(batchRecords);
            responses.add(addSmartSheetRecords(docid, sheetId, keyType, batchRecords));
        }

        return responses;
    }


    /**
     * 新增工作表请求
     *
     * @param title
     * @param rowCount
     * @param columnCount
     * @return
     */
    public static JSONObject createAddSheetRequest(String title, int rowCount, int columnCount) {
        JSONObject addSheetRequest = new JSONObject();
        addSheetRequest.put("title", title);
        addSheetRequest.put("row_count", rowCount);
        addSheetRequest.put("column_count", columnCount);
        JSONObject operation = new JSONObject();
        operation.put("add_sheet_request", addSheetRequest);
        return operation;
    }

    /**
     * 删除工作表请求
     *
     * @param sheetId
     * @return
     */
    public static JSONObject createDeleteSheetRequest(String sheetId) {
        JSONObject deleteSheetRequest = new JSONObject();
        deleteSheetRequest.put("sheet_id", sheetId);

        JSONObject operation = new JSONObject();
        operation.put("delete_sheet_request", deleteSheetRequest);
        return operation;
    }


    public static JSONObject createUpdateSheetRequest(String sheetId, int startRow, int startCol, List<List<String>> cellDataVal) {
        List<List<SpreadsheetUpdateRangeRequest.CellData>> cellData = cellDataVal.stream().map(i ->
                i.stream().map(SpreadsheetUpdateRangeRequest.CellData::new).collect(Collectors.toList())
        ).collect(Collectors.toList());
        JSONObject request = new JSONObject();
        JSONObject updateRequest = new JSONObject();
        // 构建GridData
        JSONObject gridData = new JSONObject();
        gridData.put("start_row", startRow);
        gridData.put("start_column", startCol);
        JSONArray rows = new JSONArray();
        for (List<SpreadsheetUpdateRangeRequest.CellData> row : cellData) {
            JSONObject rowData = new JSONObject();
            JSONArray values = new JSONArray();
            for (SpreadsheetUpdateRangeRequest.CellData cell : row) {
                values.add(buildCellData(cell));
            }

            rowData.put("values", values);
            rows.add(rowData);
        }

        gridData.put("rows", rows);
        updateRequest.put("sheet_id", sheetId);
        updateRequest.put("grid_data", gridData);

        request.put("update_range_request", updateRequest);
        return request;
    }


    /**
     * 构建单个单元格数据
     */
    private static JSONObject buildCellData(SpreadsheetUpdateRangeRequest.CellData cell) {
        JSONObject cellData = new JSONObject();

        // 单元格值
        JSONObject cellValue = new JSONObject();
        if (cell.getLink() != null) {
            JSONObject link = new JSONObject();
            link.put("text", cell.getText());
            link.put("url", cell.getLink());
            cellValue.put("link", link);
        } else {
            cellValue.put("text", cell.getText());
        }
        cellData.put("cell_value", cellValue);

        // 单元格格式（可选）
        if (cell.getFormat() != null) {
            cellData.put("cell_format", buildCellFormat(cell.getFormat()));
        }

        return cellData;
    }

    /**
     * 构建单元格格式
     */
    private static JSONObject buildCellFormat(SpreadsheetUpdateRangeRequest.CellFormat format) {
        JSONObject formatObj = new JSONObject();
        JSONObject textFormat = new JSONObject();

        textFormat.put("font", format.getFont());
        textFormat.put("font_size", format.getFontSize());
        textFormat.put("bold", format.isBold());
        textFormat.put("italic", format.isItalic());

        if (format.getColor() != null) {
            JSONObject color = new JSONObject();
            color.put("red", format.getColor().getRed());
            color.put("green", format.getColor().getGreen());
            color.put("blue", format.getColor().getBlue());
            color.put("alpha", format.getColor().getAlpha());
            textFormat.put("color", color);
        }

        formatObj.put("text_format", textFormat);
        return formatObj;
    }


    /**
     * Get share URL for a WeCom document
     *
     * @param docId 文档id
     * @return Share URL if successful, null if failed
     * @throws Exception If any error occurs during the API call
     */
    public static String getDocumentShareUrl(String docId) {
        if ((docId == null || docId.isEmpty())) {
            throw new IllegalArgumentException(" docId 不能为空");
        }
        String key = String.format(qwWeDocDocShareKey, docId);
        if (!redisService.hasKey(key)) {
            String url = String.format("%s/wedoc/doc_share?access_token=%s", BASE_URL, getAccessToken());

            JSONObject requestBody = new JSONObject();
            requestBody.put("docid", docId);

            try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
                HttpPost httpPost = new HttpPost(url);
                httpPost.setHeader("Content-Type", "application/json; charset=utf-8");
                httpPost.setEntity(new StringEntity(requestBody.toString(), "UTF-8"));

                try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        String responseString = EntityUtils.toString(entity, "UTF-8");
                        JSONObject jsonResponse = JSONObject.parseObject(responseString);

                        // Check for errors
                        int errCode = jsonResponse.getInteger("errcode");
                        if (errCode != 0) {
                            String errMsg = jsonResponse.getString("errmsg");
                            System.err.println("API Error: " + errCode + " - " + errMsg);
                            return null;
                        }

                        // Return the share URL
                        return jsonResponse.getString("share_url");
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            return redisService.getString(key);
        }
        return null;
    }


//dcpemt4SNRvS2qbbDtUTINJSz6nX6ljvpdpzNtR7H4aGCkL67Uzya05wxC2_6MBbt8iIo150Y8CxBRq5SG_jR8mw
//dcXXYG4IAmiayvtyuBM43sBxVk0KL2iHk9FlhBizleUiz7_BSin_6VgXXXTuJrN0ReGgVGdgIqQD3oaLaOBg_kdw
//    public static void main(String[] args) {
//        System.out.println(getDocumentShareUrl("dc9WLZmBkJKeHzgfx0Dc_7J8XBo-l_vx_PejgLqjtNXfO34wdNPwBYh-lzyd_IuePadG3HIhHZbCdMgtl3PxJZqA"));
    // CreateDocResponse response = createDocument(4, "江高韵达快递拦截", null, null);
//       String docId = "dcGTJVolmozTJA2u7zWvohUSwPD-Ezh8sfraw3LIyVw9AhKyWz1BxHIsjIn87tUQWcWENS8X_2sZqSJdouAjKZFQ";
//       SpreadSheetGetSheetPropertiesResponse spreadSheetGetSheetProperties = spreadSheetGetSheetProperties(docId);
//       System.out.println(spreadSheetGetSheetProperties);
//   JSONObject response = batchUpdateSpreadsheet("dcalkAfPGxsUlw493mzSZm3OFbUIsxtjEHMnsT-3JOUyz-k40yg_pS8UOybaxTfPD2L7aJO9VMv9AWUhdTMpcQ0A", createAddSheetRequest("2025-07",10,10));
//   JSONObject response = batchUpdateSpreadsheet("dcalkAfPGxsUlw493mzSZm3OFbUIsxtjEHMnsT-3JOUyz-k40yg_pS8UOybaxTfPD2L7aJO9VMv9AWUhdTMpcQ0A", createAddSheetRequest("2025-07",10,10));
//   System.out.println(response);
//sVsKJz 5Y6dyX
//       SpreadSheetGetSheetPropertiesResponse spreadSheetGetSheetProperties = spreadSheetGetSheetProperties("dcalkAfPGxsUlw493mzSZm3OFbUIsxtjEHMnsT-3JOUyz-k40yg_pS8UOybaxTfPD2L7aJO9VMv9AWUhdTMpcQ0A");
//    System.out.println(spreadSheetGetSheetProperties);
//  shade.com.alibaba.fastjson2.JSONObject bsResult = batchUpdateSpreadsheet("dcalkAfPGxsUlw493mzSZm3OFbUIsxtjEHMnsT-3JOUyz-k40yg_pS8UOybaxTfPD2L7aJO9VMv9AWUhdTMpcQ0A", createAddSheetRequest("2025-07",1000,1000));
//      System.out.println(batchUpdateSpreadsheet("dcalkAfPGxsUlw493mzSZm3OFbUIsxtjEHMnsT-3JOUyz-k40yg_pS8UOybaxTfPD2L7aJO9VMv9AWUhdTMpcQ0A", createAddSheetRequest("2025-07",600,10)));


//          System.out.println(batchUpdateSpreadsheet(docId,createDeleteSheetRequest("ZhqwaM")));
//
////         SpreadSheetGetSheetPropertiesResponse response = spreadSheetGetSheetProperties(docId);
////System.err.println(response);
//        String dateStr="2025-6-31";
//        String sheetId="2025-6-27";
//        Integer rowCount=1;
//        List<SpreadSheetGetSheetPropertiesItem>singleton= spreadSheetGetSheetProperties.getProperties().stream().filter(prp -> ObjectUtil.equal(prp.getTitle(), dateStr)).collect(Collectors.toList());
//        if(!singleton.isEmpty()){
//           sheetId=singleton.get(0).getSheetId();
//           rowCount=singleton.get(0).getRowCount();
//       }else{
//            JSONObject bsResult = batchUpdateSpreadsheet(docId, createAddSheetRequest(dateStr,100,100));
//            sheetId = bsResult.getJSONArray("responses").getJSONObject(0).getJSONObject("add_sheet_response").getJSONObject("properties").getString("sheet_id");
//            JSONObject updateRequest = batchUpdateSpreadsheet(docId,createUpdateSheetRequest(sheetId, 0, 0, Collections.singletonList(Arrays.asList("名称","数字","中文"))));
//            rowCount=1;
//       }
//        // 准备测试数据（2行3列）
//        List<List<String>> data = Arrays.asList(
//                Arrays.asList(
//                        "姓名",
//                        "年龄",
//                        "官网"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "1"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "2"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "3"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "4"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "5"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "6"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "7"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "8"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "9"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "10"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "11"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "13"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "2"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "33"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "333"
//                ),
//                Arrays.asList(
//                        "张三",
//                        "25",
//                        "33333"
//                )
//        );

    // 构建更新请求（从第2行第1列开始写入）
//        JSONObject updateRequest = createUpdateSheetRequest(sheetId, rowCount, 0, data);
//        String docId = "dcfAVqB80vYyZh5Q4Dg1GC_hCljUmnKOBrDNufkO1mO9rjnXikb2Ssx2VI-8eYJ7mC18zZEt8tCAf2vcpWRDT2Jw";
//        List<List<List<String>>> batchesData = createBatches(data);
//       for(List<List<String>> bData:batchesData){
//        batchUpdateSpreadsheet(docId,createUpdateSheetRequest(sheetId, rowCount, 0, bData));
//        rowCount=rowCount+bData.size();
//       }
    //      JSONObject response = batchUpdateSpreadsheet("dcfAVqB80vYyZh5Q4Dg1GC_hCljUmnKOBrDNufkO1mO9rjnXikb2Ssx2VI-8eYJ7mC18zZEt8tCAf2vcpWRDT2Jw", createAddSheetRequest("测试新",10,10));


//        System.err.println(response);
//        CreateDocResponse response = createDocument(4, "最新的测试", null, null);
//        System.err.println(response.getDocid());
    //dcfAVqB80vYyZh5Q4Dg1GC_hCljUmnKOBrDNufkO1mO9rjnXikb2Ssx2VI-8eYJ7mC18zZEt8tCAf2vcpWRDT2Jw

    //        getDocBaseInfo();
//        SmartsheetGetSheetResponse dcpemt4SNRvS2qbbDtUTINJSz6nX6ljvpdpzNtR7H4aGCkL67Uzya05wxC26MBbt8iIo150Y8CxBRq5SGJR8mw = smartsheetGetSheet("dcpemt4SNRvS2qbbDtUTINJSz6nX6ljvpdpzNtR7H4aGCkL67Uzya05wxC2_6MBbt8iIo150Y8CxBRq5SG_jR8mw", null);
//        System.out.println(jsonObject);
//   addSheet("dc8WAaq3Hk7_HQWlXfK-J-Z_jBkmz-jJhtM8ueaDXbjAA4ZNQmnslAKVQWLegOI2TMA-Hjr92Ui-G_NYJKSQCSfA","测试23",2);
//        GetDocInfoResponse dc41GbGs22z1MtCkQStC6HvyqAHpTqa4UCM8Jx2wDMX45zeGmN5bDFNeRJP6lc9BU0CSrQkxAQq6gLPU3m6wymw = getDocBaseInfo("dc41GbGs22z1MtCkQStC6HvyqAHpTqa4UCM8Jx2wDMX45zeGmN5bDFNeR_jP6lc9BU0CSrQkxAQq6gLPU3m6wymw");
//        System.out.println(getDocBaseInfo("dc1UaV81KE_68DJcZxQ7pXn4styTMUdZvFPdrTKH-bZb_N3KWDopiaBakDxlJtjILUIcVrIRoAC1-RnZoI6I_5YQ"));
//        System.out.println(getDocBaseInfo("dcXXYG4IAmiayvtyuBM43sBxVk0KL2iHk9FlhBizleUiz7_BSin_6VgXXXTuJrN0ReGgVGdgIqQD3oaLaOBg_kdw"));
//        addFields()
//        System.out.println(getAccessToken());
//    }


    /**
     * 将大数据分割成符合限制的小批次
     *
     * @param data 原始数据
     * @return 分批后的数据列表
     */
    private static List<List<List<String>>> createBatches(List<List<String>> data) {
        if (data == null) return Collections.emptyList();
        if (data.isEmpty()) return Collections.singletonList(Collections.emptyList());
        int colCount = data.get(0).size();
        if (colCount > MAX_RANGE_COLUMNS) {
            throw new IllegalArgumentException(
                    String.format("列数%d超过最大限制200", colCount)
            );
        }
        int maxRowsPerBatch = Math.min(
                MAX_RANGE_ROWS,
                MAX_TOTAL_CELLS / colCount
        );
        // 分批处理
        List<List<List<String>>> batches = new ArrayList<>();
        int totalRows = data.size();
        for (int i = 0; i < totalRows; i += maxRowsPerBatch) {
            int end = Math.min(i + maxRowsPerBatch, totalRows);
            batches.add(new ArrayList<>(data.subList(i, end)));
        }
        return batches;
    }


    /**
     * 导入数据
     *
     * @param workbookId
     * @param sheetId
     * @param values
     * @param currentSubscript
     */
    public static void importValuesData(String workbookId, String sheetId, List<List<String>> values, Integer currentSubscript) {
        batchUpdateSpreadsheetRecord(workbookId, sheetId, currentSubscript, values);
    }

    /**
     * 批量更新表格内容
     *
     * @param docId   文档ID
     * @param sheetId 工作表ID
     * @param data    批量操作请求列表
     * @return 返回结果
     */
    public static void batchUpdateSpreadsheetRecord(String docId, String sheetId, Integer rowCount, List<List<String>> data) {
        List<List<List<String>>> batchesData = createBatches(data);
        for (List<List<String>> bData : batchesData) {
            batchUpdateSpreadsheet(docId, createUpdateSheetRequest(sheetId, rowCount, 0, bData));
            rowCount = rowCount + bData.size();
        }
    }

    public static JSONObject optimizeTable(String workbookId, String sheetId, List<String> headerValues) {
        SpreadSheetGetSheetPropertiesResponse spreadSheetGetSheetProperties = spreadSheetGetSheetProperties(workbookId);
        String dateStr = sheetId;
        Integer rowCount = 1;
        List<SpreadSheetGetSheetPropertiesItem> singleton = spreadSheetGetSheetProperties.getProperties().stream().filter(prp -> ObjectUtil.equal(prp.getTitle(), dateStr)).collect(Collectors.toList());
        if (!singleton.isEmpty()) {
            sheetId = singleton.get(0).getSheetId();
            rowCount = singleton.get(0).getRowCount();
        } else {
            shade.com.alibaba.fastjson2.JSONObject bsResult = batchUpdateSpreadsheet(workbookId, createAddSheetRequest(dateStr, 600, 10));
            sheetId = bsResult.getJSONArray("responses").getJSONObject(0).getJSONObject("add_sheet_response").getJSONObject("properties").getString("sheet_id");
            shade.com.alibaba.fastjson2.JSONObject updateRequest = batchUpdateSpreadsheet(workbookId, createUpdateSheetRequest(sheetId, 0, 0, Collections.singletonList(headerValues)));
            rowCount = 1;
        }
        JSONObject param = new JSONObject();
        param.put("sheetId", sheetId);
        param.put("rowCount", rowCount);
        return param;
    }

    public static void updateDocumentSending(String workbookId, String secret, String token, List<String> atMobiles, List<String> atUserIds, List<List<String>> values,
                                             String sheetId, List<String> headerValues, String msgTitle, String msgTemplate, String endingContent, String rangeAddressTemplate, Integer updateBatchSize, Integer dataSaveDays, TimeUnit timeUnit, String keyTemplate) {
//        String workbookId = param.getWorkbookId();
//        String secret = param.getSecret();
//        String token = param.getToken();
        shade.com.alibaba.fastjson2.JSONObject qwotResult = WeChatUtil.optimizeTable(workbookId, sheetId, headerValues);
        Integer currentSubscript = qwotResult.getInteger("rowCount");
        sheetId = qwotResult.getString("sheetId");
        WeChatUtil.importValuesData(workbookId, sheetId, values, currentSubscript);
        List<List<List<String>>> partitionValues = Lists.partition(values, 8);
        for (int i = 0; i < partitionValues.size(); i++) {
            String content = msgTitle.concat("\n");
            List<List<String>> pv = partitionValues.get(i);
            content = content.concat(pv.stream().map(cpv -> String.format(msgTemplate, cpv.toArray()).concat("\n")).collect(Collectors.joining("\n")));
            content = content.concat("\n").concat(endingContent);
//            if (partitionValues.size()==i){
            content = content.concat("\n").concat(Objects.requireNonNull(getDocumentShareUrl(workbookId)));
//            }
            WeChatUtil.sendTextMessage(secret, content, false);
        }
//        List<List<String>> partitionValues = groupBy2048Bytes(values);
//        for(int i=0;i<partitionValues.size();i++){
//            List<String>pv=partitionValues.get(i);
//            String content=msgTitle.concat("\n");
//            content=content.concat(String.format(msgTemplate,pv.toArray()).concat("\n"));
//            content=content.concat("\n").concat(endingContent);
//            content=content.concat("\n").concat(Objects.requireNonNull(getDocumentShareUrl(workbookId)));
//            WeChatUtil.sendTextMessage(secret,content,false);
//        }

    }


    public static List<List<String>> groupBy2048Bytes(List<List<String>> values) {
        List<List<String>> result = new ArrayList<>();
        List<String> currentGroup = new ArrayList<>();
        int currentSize = 0;

        for (List<String> sublist : values) {
            for (String str : sublist) {
                byte[] strBytes = str.getBytes(StandardCharsets.UTF_8);
                int strSize = strBytes.length;

                // 处理超大字符串(单独超过2048字节)
                if (strSize > 2048) {
                    // 先保存当前组(如果有内容)
                    if (!currentGroup.isEmpty()) {
                        result.add(currentGroup);
                        currentGroup = new ArrayList<>();
                        currentSize = 0;
                    }
                    // 将大字符串单独作为一组
                    result.add(Collections.singletonList(str));
                    continue;
                }

                // 检查是否超过限制
                if (currentSize + strSize > 2048) {
                    result.add(currentGroup);
                    currentGroup = new ArrayList<>();
                    currentSize = 0;
                }

                currentGroup.add(str);
                currentSize += strSize;
            }
        }

        // 添加最后一组
        if (!currentGroup.isEmpty()) {
            result.add(currentGroup);
        }

        return result;
    }

    public static void bySheetNameDel(String workbookId, String sheetName) {
        SpreadSheetGetSheetPropertiesResponse spreadSheetGetSheetProperties = spreadSheetGetSheetProperties(workbookId);
        String sheetId = "";
        List<SpreadSheetGetSheetPropertiesItem> singleton = spreadSheetGetSheetProperties.getProperties().stream().filter(prp -> ObjectUtil.equal(prp.getTitle(), sheetName)).collect(Collectors.toList());
        if (!singleton.isEmpty()) {
            SpreadSheetGetSheetPropertiesItem spreadSheetGetSheetPropertiesItem = singleton.get(0);
            sheetId = spreadSheetGetSheetPropertiesItem.getSheetId();
            JSONObject jsonObject = batchUpdateSpreadsheet(workbookId, createDeleteSheetRequest(sheetId));
            System.out.println(jsonObject);
        }
    }

    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 添加智能表格子表
     *
     * @param docId 文档ID
     * @param title 子表标题
     * @param index 子表位置索引
     * @return 添加结果响应
     */
    public static AddSmartSheetResponse addSmartSheetSheet(String docId, String title, int index) {
        String url = String.format("%s/wedoc/smartsheet/add_sheet?access_token=%s", BASE_URL, getAccessToken());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);

            // 设置请求头
            httpPost.setHeader("Content-Type", "application/json");

            // 构建请求体
            AddSmartSheetRequest request = new AddSmartSheetRequest();
            request.setDocid(docId);

            AddSmartSheetRequest.Properties properties = new AddSmartSheetRequest.Properties();
            properties.setTitle(title);
            properties.setIndex(index);
            request.setProperties(properties);

            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());

                // 解析响应
                return objectMapper.readValue(responseBody, AddSmartSheetResponse.class);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 文档重命名
     *
     * @param docId   文档ID (与formId二选一)
     * @param formId  收集表ID (与docId二选一)
     * @param newName 新名称(最多255字符)
     * @return 重命名结果响应
     */
    public static RenameDocResponse renameSmartSheetDocument(String docId, String formId, String newName) {
        String url = String.format("%s/wedoc/rename_doc?access_token=%s", BASE_URL, getAccessToken());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);

            // 设置请求头
            httpPost.setHeader("Content-Type", "application/json");

            // 构建请求体
            RenameDocRequest request = new RenameDocRequest(docId, formId, newName);
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());

                // 检查HTTP状态码
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("HTTP请求失败: " + response.getStatusLine());
                }

                // 解析响应
                RenameDocResponse apiResponse = objectMapper.readValue(responseBody, RenameDocResponse.class);

                // 检查API错误码
                if (!apiResponse.isSuccess()) {
                    throw new RuntimeException("企业微信API错误: " + apiResponse.getErrMsg() +
                            " (errcode: " + apiResponse.getErrCode() + ")");
                }

                return apiResponse;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询智能表子表数据
     *
     * @param docid   文档id
     * @param sheetId 子表id
     * @return 子表查询结果
     */
    public static SmartSheetQueryResponse querySmartSheetSheet(String docid, String sheetId) {
        String url = String.format("%s/wedoc/smartsheet/get_sheet?access_token=%s", BASE_URL, getAccessToken());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            SmartSheetQueryRequest request = new SmartSheetQueryRequest(docid, sheetId, true);
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("HTTP请求失败: " + response.getStatusLine());
                }
                SmartSheetQueryResponse apiResponse = objectMapper.readValue(responseBody, SmartSheetQueryResponse.class);
                if (!apiResponse.isSuccess()) {
                    throw new RuntimeException("企业微信API错误: " + apiResponse.getErrMsg() +
                            " (errCode: " + apiResponse.getErrCode() + ")");
                }
                return apiResponse;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询智能表记录
     *
     * @param docId
     * @param sheetId
     * @param limit
     * @return
     */
    public static GetSmartSheetRecordsResponse getSmartSheetRecords(String docId, String sheetId, Integer limit) {
        GetSmartSheetRecordsRequest request = new GetSmartSheetRecordsRequest();
        request.setDocid(docId);
        request.setSheet_id(sheetId);
        request.setKey_type("CELL_VALUE_KEY_TYPE_FIELD_TITLE");
        if (ObjectUtil.isNull(limit)) {
            limit = 100;
        }
        request.setLimit(limit);
        String url = String.format("%s/wedoc/smartsheet/get_records?access_token=%s", BASE_URL, getAccessToken());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("HTTP请求失败: " + response.getStatusLine());
                }
                GetSmartSheetRecordsResponse apiResponse = objectMapper.readValue(responseBody, GetSmartSheetRecordsResponse.class);
                if (!apiResponse.isSuccess()) {
                    throw new RuntimeException("企业微信API错误: " + apiResponse.getErrMsg() +
                            " (errCode: " + apiResponse.getErrCode() + ")");
                }
                return apiResponse;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取表格字段信息
     *
     * @param docId   文档ID
     * @param sheetId 表格ID
     * @return 字段列表
     */
    public static FieldQueryResponse getSmartSheetFields(String docId, String sheetId, String viewId, List<String> fieldIds, List<String> fieldTitles, Integer offset, Integer limit) {
        FieldQueryRequest request = new FieldQueryRequest();
        request.setDocid(docId);
        request.setLimit(limit);
        request.setOffset(offset);
        request.setView_id(viewId);
        request.setSheet_id(sheetId);
        request.setField_ids(fieldIds);
        request.setField_titles(fieldTitles);
        String url = String.format("%s/wedoc/smartsheet/get_fields?access_token=%s", BASE_URL, getAccessToken());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("HTTP请求失败: " + response.getStatusLine());
                }
                FieldQueryResponse apiResponse = objectMapper.readValue(responseBody, FieldQueryResponse.class);
                if (!apiResponse.isSuccess()) {
                    throw new RuntimeException("企业微信API错误: " + apiResponse.getErrMsg() +
                            " (errcode: " + apiResponse.getErrCode() + ")");
                }
                return apiResponse;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 获取智能表格字段信息
     *
     * @param docId   文档ID
     * @param sheetId 表格ID
     * @return 字段列表
     */
    public static FieldQueryResponse getSmartSheetFields(String docId, String sheetId) {
        return getSmartSheetFields(docId, sheetId, null, null, null, 0, 100);
    }

    /**
     * 删除智能表格字段
     *
     * @param docId    文档ID
     * @param sheetId  表格ID
     * @param fieldIds 要删除的字段ID列表
     * @return 是否删除成功
     * @throws RuntimeException 当API调用失败时抛出
     */
    public static DeleteSmartSheetFieldsResponse deleteSmartSheetFields(String docId, String sheetId, List<String> fieldIds) {
        DeleteSmartSheetFieldsRequest request = new DeleteSmartSheetFieldsRequest();
        request.setDocid(docId);
        request.setSheet_id(sheetId);
        request.setField_ids(fieldIds);
        String url = String.format("%s/wedoc/smartsheet/delete_fields?access_token=%s", BASE_URL, getAccessToken());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("HTTP请求失败: " + response.getStatusLine());
                }
                DeleteSmartSheetFieldsResponse apiResponse = objectMapper.readValue(responseBody, DeleteSmartSheetFieldsResponse.class);
                if (!apiResponse.isSuccess()) {
                    throw new RuntimeException("企业微信API错误: " + apiResponse.getErrMsg() +
                            " (errcode: " + apiResponse.getErrCode() + ")");
                }
                return apiResponse;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 添加智能表格字段
     *
     * @param docId       文档ID
     * @param sheetId     表格ID
     * @param fieldsToAdd 要添加的字段列表
     * @return 添加成功的字段信息列表
     * @throws RuntimeException 当API调用失败时抛出
     */
    public static AddSmartSheetFieldsResponse addSmartSheetFields(String docId, String sheetId, List<AddSmartSheetFieldsRequest.AddField> fieldsToAdd) {
        AddSmartSheetFieldsRequest request = new AddSmartSheetFieldsRequest();
        request.setDocid(docId);
        request.setSheet_id(sheetId);
        request.setFields(fieldsToAdd);
        String url = String.format("%s/wedoc/smartsheet/add_fields?access_token=%s", BASE_URL, getAccessToken());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("HTTP请求失败: " + response.getStatusLine());
                }
                AddSmartSheetFieldsResponse apiResponse = objectMapper.readValue(responseBody, AddSmartSheetFieldsResponse.class);
                if (!apiResponse.isSuccess()) {
                    throw new RuntimeException("企业微信API错误: " + apiResponse.getErrMsg() +
                            " (errcode: " + apiResponse.getErrCode() + ")");
                }
                return apiResponse;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 删除智能表格子表
     *
     * @param docId   文档ID
     * @param sheetId 子表ID
     * @return 是否删除成功
     * @throws RuntimeException 当API调用失败时抛出
     */
    public static DeleteSmartSheetSheetResponse deleteSmartSheetSheet(String docId, String sheetId) {
        // 构建请求
        DeleteSmartSheetSheetRequest request = new DeleteSmartSheetSheetRequest();
        request.setDocid(docId);
        request.setSheet_id(sheetId);
        String url = String.format("%s/wedoc/smartsheet/delete_sheet?access_token=%s", BASE_URL, getAccessToken());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("HTTP请求失败: " + response.getStatusLine());
                }
                DeleteSmartSheetSheetResponse apiResponse = objectMapper.readValue(responseBody, DeleteSmartSheetSheetResponse.class);
                if (!apiResponse.isSuccess()) {
                    throw new RuntimeException("企业微信API错误: " + apiResponse.getErrMsg() + " (errcode: " + apiResponse.getErrCode() + ")");
                }
                return apiResponse;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    public static void main(String[] args) {
//        List<String> list = Arrays.asList(
//                "dcs8N3YnSkv8s--L4oQQD_Blv4qQeN8em4iFizYma4-PccrSDe3citeMUH5RC7VKXY9YqeMWI2iwee9ZnW64gWTQ",
//                "dc9WLZmBkJKeHzgfx0Dc_7J8XBo-l_vx_PejgLqjtNXfO34wdNPwBYh-lzyd_IuePadG3HIhHZbCdMgtl3PxJZqA",
//                "dcJ0Pwc7k1zsiYOygwlSGxipX0rGz43g-ISqV_YIHfPonkkYBM_vutaBMJbUYi-42xD5FtUED7zzURYjoKA0pdNw",
//                "dcMbmjKY-pT5R2pfWChZ3Nicgk-5vMI1ok9yWsTPHDg513juX3kEoWtsOl8it0TC4xbE7mGsMrQk4sK_PUj6VRVw",
//                "dckAc2wbedgiH48D0MbpP6iEIXP9XrjEUsMVZb83IvxJxrg8yppSxdlgQ96J2KVMXivAb1e3d4_JAohTssixwSQw"
//        );
//        for(String workbookId:list){
//            bySheetNameDel(workbookId,"2025-07");
//            bySheetNameDel(workbookId,"测试新");
//            bySheetNameDel(workbookId,"测试");
//        }
    }

    public static void updateAiExcelSendMsg(String workbookId, String secret, String token, List<String> atMobiles, List<String> atUserIds, List<List<String>> values,
                                            String sheetName, List<String> headerValues, String msgTitle, String msgTemplate, String endingContent, Integer updateBatchSize) {
        String sheetId = "";
        SmartSheetQueryResponse smartSheetQueryResponse = WeChatUtil.querySmartSheetSheet(workbookId, null);
        List<SmartSheetQueryResponse.SheetInfo> sheetItem = smartSheetQueryResponse.getSheetList().stream().filter(sl -> ObjectUtil.equal(sheetName, sl.getTitle())).collect(Collectors.toList());
        if (sheetItem.isEmpty()) {
            AddSmartSheetResponse addSmartSheetResponse = WeChatUtil.addSmartSheetSheet(workbookId, sheetName, 0);
            sheetId = addSmartSheetResponse.getProperties().getSheetId();
            for (SmartSheetQueryResponse.SheetInfo si : smartSheetQueryResponse.getSheetList()) {
                if (!ObjectUtil.equal(si.getTitle(), sheetName)) {
                    WeChatUtil.deleteSmartSheetSheet(workbookId, si.getSheetId());
                }
            }
            List<AddSmartSheetFieldsRequest.AddField> addFields = headerValues.stream().map(whv -> new AddSmartSheetFieldsRequest.AddField(whv, WeChatFieldType.FIELD_TYPE_TEXT.getCode())).collect(Collectors.toList());
            //创建字段
            AddSmartSheetFieldsResponse addSmartSheetFieldsResponses = WeChatUtil.addSmartSheetFields(workbookId, sheetId, addFields);
            List<String> addFieldIds = addSmartSheetFieldsResponses.getFields().stream().map(AddSmartSheetFieldsResponse.Field::getFieldId).collect(Collectors.toList());
            FieldQueryResponse smartSheetFields = WeChatUtil.getSmartSheetFields(workbookId, sheetId, null, null, null, 0, 100);
            List<String> fields = smartSheetFields.getFields().stream().map(FieldQueryResponse.Field::getFieldId).filter(fieldId -> !addFieldIds.contains(fieldId)).collect(Collectors.toList());
            DeleteSmartSheetFieldsResponse deleteSmartSheetFieldsResponse = WeChatUtil.deleteSmartSheetFields(workbookId, sheetId, fields);
        } else {
            sheetId = sheetItem.get(0).getSheetId();
        }

        // 2. 构建记录列表
        List<AddSmartSheetRecordsRequest.Record> records = new ArrayList<>();
        for (List<String> value : values) {
            Map<String, List<AddSmartSheetRecordsRequest.Record.CellValue>> recordCellValue = new HashMap<>();
            for (int i = 0; i < headerValues.size(); i++) {
                recordCellValue.put(headerValues.get(i), Collections.singletonList(AddSmartSheetRecordsRequest.Record.CellValue.createText(value.get(i))));
            }
            records.add(new AddSmartSheetRecordsRequest.Record(recordCellValue));
        }
        // 3. 调用API添加记录
        List<AddSmartSheetRecordsResponse> responses = WeChatUtil.addSmartSheetRecordsBatch(workbookId, sheetId, null, records, updateBatchSize);
//        List<AddSmartSheetFieldsRequest.AddField> allFields= values.stream().map(v->new AddSmartSheetFieldsRequest.AddField()).collect(Collectors.toList());
//        WeChatUtil.addSmartSheetFieldsBatch(workbookId,sheetId,)
        List<List<List<String>>> partitionValues = Lists.partition(values, 8);
        for (int i = 0; i < partitionValues.size(); i++) {
            String content = msgTitle.concat("\n");
            List<List<String>> pv = partitionValues.get(i);
            content = content.concat(pv.stream().map(cpv -> String.format(msgTemplate, cpv.toArray()).concat("\n")).collect(Collectors.joining("\n")));
            content = content.concat("\n").concat(endingContent);
//            if (partitionValues.size()==i){
            content = content.concat("\n").concat(Objects.requireNonNull(getDocumentShareUrl(workbookId)));
//            }
            WeChatUtil.sendMessage(token, RobotMessage.initMessage(content));

        }


    }


    /**
     * 手机号获取userid
     */
    public static String getUserIdByPhone(String phone) {
        // 初始化
        String userId = null;
        // 数据组装
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("mobile", phone);
        String url = String.format("%s/user/getuserid?access_token=%s", BASE_URL, getAccessToken());
        try {
            log.info("企微手机号获取userid请求参数:{}", bodyJson.toJSONString());
            String result = HttpUtil.doPost(url, bodyJson.toJSONString());
            log.info("企微手机号获取userid返回结果:{}", result);
            WechatGetUserIdByPhoneResponse response = JSON.parseObject(result, WechatGetUserIdByPhoneResponse.class);
            if (response.getErrCode() != 0) {
                throw new RuntimeException(response.getErrMsg());
            }
            userId = response.getUserid();
        } catch (Exception e) {
            log.error("企微手机号获取userid调用失败:", e);
        }
        return userId;
    }

    /**
     * 创建成员
     */
    public static boolean createMember(WechatCreateMemberRequest request) {
        String url = String.format("%s/user/create?access_token=%s", BASE_URL, getMemberAccessToken());
        try {
            String bodyJson = JSON.toJSONString(request);
            log.info("企微创建成员请求参数:{}", bodyJson);
            String result = HttpUtil.doPost(url, bodyJson);
            log.info("企微创建成员返回结果:{}", result);
            WeComApiResponse response = JSON.parseObject(result, WeComApiResponse.class);
            if (response.getErrCode() != 0) {
                throw new RuntimeException(response.getErrMsg());
            }
        } catch (Exception e) {
            log.error("企微创建成员调用失败:", e);
            return false;
        }
        return true;
    }

    /**
     * 删除成员
     */
    public static boolean deleteMember(String userId) {
        String url = String.format("%s/user/delete?access_token=%s&userid=%s", BASE_URL, getMemberAccessToken(), userId);
        try {
            log.info("企微删除成员请求参数:{}", userId);
            String result = HttpUtil.doGet(url);
            log.info("企微删除成员返回结果:{}", result);
            WeComApiResponse response = JSON.parseObject(result, WeComApiResponse.class);
            if (response.getErrCode() != 0) {
                throw new RuntimeException(response.getErrMsg());
            }
        } catch (Exception e) {
            log.error("企微删除成员调用失败:", e);
            return false;
        }
        return true;
    }

}
